
import java.io.IOException;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.Sprite;



public class Game extends GameCanvas{

    
    public static boolean iscontinue = false;
    public int score = 20;
   public readWriteFile rw= new  readWriteFile();
    public playmusic abcplay= new playmusic();
    public boolean isSound = true;
    private Ball [][] ArrayOfBall;
    private int last_i=-1;
    private int last_j=-1;
    private int nMine=0;
    private int nMineOut=0;
    private int nMineAround=0;
    private int level;
    private boolean is_up_level;
    private boolean use_press;
    private boolean createdMineField;
    private boolean ispause;
     private TimeCount Timecount;
    private Timer mTimer;
    private Timer cTimer;
    private Timer raceTimer;
    private TimerTask clock;

  
    private Graphics g;
    private Pointer p;
 
   

    
   

    private Image bg;
  
    private Image startInfo;
  
  
    private Sprite countDown;
    private Image balls;
    private Image digital;
  
    private boolean stopped = true;
   

    private Engine engine = new Engine();

  
    private SimpleThread gameLogic;
    private Thread countdownThread;
  
    private int timecountdown;
    private int pauseCounter = 0;
    private String error = "";
    private Font smallFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_ITALIC, Font.SIZE_SMALL);
    private Font bigFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_ITALIC, Font.SIZE_LARGE);
    public Game() {
        super(false);
        setFullScreenMode(true);
       
         Timecount=new TimeCount();
        loadGraphics();
        createBalls();
        engine.start();
        p=null;
        level=0;
        is_up_level=true;
     
    }

    public void showNotify() {

       mTimer = new Timer();
      
        g = getGraphics();

        if(is_up_level) UpLevel();
        TimerTask ui = new TimerTask() { // phụ trách vẽ

            public void run() {
                render(g);
                flushGraphics();
            }
        };
       
        gameLogic = new SimpleThread(40) { // phụ trách tính toán trong game

            public void execute() {
                if (!stopped) {
                   
                  //  if(is_up_level) UpLevel();

                }
            }
        };
        ///////////
      
       
        gameLogic.start();
       
        mTimer.schedule(ui, 0, 40);
      
  
         
       

        countdownThread = new Thread() {
            public void run() {
                try {
                     if(ispause) StartTime();
                    ispause=false;
                    countDown.setFrame(0);
                    pauseCounter = 1;
                    Thread.sleep(1000);
                    countDown.nextFrame();
                    pauseCounter = 2;
                    Thread.sleep(1000);
                    countDown.nextFrame();
                    pauseCounter = 3;
                    Thread.sleep(1000);
                    countDown.nextFrame();
                    Thread.sleep(700);
                    stopped = false;
                  
                  //  raceTimer.scheduleAtFixedRate(clock, 10, 10);
                } catch (InterruptedException ie) {
                }
            }
        };
        countdownThread.start();

      /*  if(isSound)
//            engine.on();
            abcplay.playfile("999_doa_hong.mid");*/
        
    }
     public void cleanTrackResources() {
       
        System.gc();
    }
    public void hideNotify() {
         mTimer.cancel();
         cTimer.cancel();
         countdownThread.interrupt();
         ispause=true;
    
        rw.deleteRecStore(iscontinue);
        for(int i= 0 ; i< 9; i++){
            for(int j =0 ; j<9; j++){
                if(ArrayOfBall[i][j].ismine)
                    rw.writeOneRecord("1", false);
                else
                    rw.writeOneRecord("0", false);
            }
        }
//        rw.read(true);
//        int tempScore = Integer.parseInt(rw.sc);
//        if(score > tempScore){
//            rw.deleteRecStore(true);
            rw.writeOneRecord(Integer.toString(10), true);
//        }
//        System.out.print(score+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
        
    }

    private void render(Graphics g) {
         int anchor = g.TOP | g.LEFT;
        
        g.setColor(0xFFFFFF);
        g.fillRect(0, 0, getWidth(), getHeight());
      //  balls.setPosition(carXPosition, carYPosition);
        g.drawImage(bg, 0, 0, anchor);
       
       for(int i=0;i<9;i++)
            for(int j=0;j<9;j++)
            {
                ArrayOfBall[i][j].render(g);
            }
        if (stopped) {
            g.drawImage(startInfo, 0, 66, anchor);
            countDown.paint(g);
        }
        Timecount.Render(g);
        if(p!=null) p.render(g);
        //drawDebugData(g);
    }

    protected void pointerPressed(int x, int y) {
        if(stopped) return;
         for(int i=0;i<9;i++)
            for(int j=0;j<9;j++)
            {
                if(i!=last_i||j!=last_j)
                if(ArrayOfBall[i][j].OnSelelected(x, y))
                {
                  if(last_i!=-1) ArrayOfBall[last_i][last_j].istouched=false;
                  last_i=i;
                  last_j=j;
                  i=9;
                  break;
                }
            }
            p=null;
    }
    private void StartTime(){
         cTimer=new Timer();
         TimerTask timecount = new TimerTask() { // phụ trách vẽ

            public void run() {
               Timecount.Up();
            }
        };
          cTimer.scheduleAtFixedRate(timecount, 0,1000);
    }
    protected void pointerReleased(int x, int y) {

    }

    protected void keyPressed(int keyCode) {
        if(stopped) return;
            if(p==null) // khởi tạo vị trí cho con trỏ
        {
            if(last_i==-1) // nếu chưa chọn bất kì quả trứng nào
            {
                last_i=4;
                last_j=4;
            }
            // đã chọn 1 quả trứng
            p = new Pointer(ArrayOfBall[last_i][last_j].getX(), ArrayOfBall[last_i][last_j].getY());
        }
        switch (keyCode) {
            case GameCanvas.KEY_NUM2:{ // di chuyển con trỏ lên
                ArrayOfBall[last_i][last_j].istouched=false; // bỏ chọn quả trứng hiện tại
                last_j--;
               if(last_j<0) last_j=0;
               else
               {
                   p.Up();
               }
               ArrayOfBall[last_i][last_j].OnSelected();
            }
                break;
            case GameCanvas.KEY_NUM4:{
                ArrayOfBall[last_i][last_j].istouched=false;
                last_i--;
               if(last_i<0) last_i=0;
               else
               {
                   p.Left();
               }
               ArrayOfBall[last_i][last_j].OnSelected();
            }
                break;
            case GameCanvas.KEY_NUM6:{
                ArrayOfBall[last_i][last_j].istouched=false;
                last_i++;
               if(last_i>8) last_i=8;
               else
               {
                   p.Right();
               }
               ArrayOfBall[last_i][last_j].OnSelected();
            }
                break;
             case GameCanvas.KEY_NUM8:{
                 ArrayOfBall[last_i][last_j].istouched=false;
                last_j++;
               if(last_j>8) last_j=8;
               else
               {
                   p.Down();
               }
               ArrayOfBall[last_i][last_j].OnSelected();
             }
                break;
            case GameCanvas.KEY_NUM1:{
            }
                break;
            case GameCanvas.KEY_NUM3:{
            }
                break;
             case GameCanvas.KEY_NUM5:{
                 if(!createdMineField) 
                 {
                     createMineField();
                     StartTime();
                 }

             }
                break;
        }

    }

    private void loadGraphics() {
        try {
            ImageLoader loader = ImageLoader.getInstance();
            balls=loader.loadImage("/balls.png");
          /*  balls = new Sprite(loader.loadImage("/balls.png"), 25, 25);
            balls.setRefPixelPosition(25, 25);
          //  balls.setPosition(carXPosition, carYPosition);
            balls.setFrame(currentFrame);
           */
            countDown = new Sprite(loader.loadImage("/countdown_240x121.png"), 240, 121);
            digital=loader.loadImage("/numbers.png");
            countDown.setPosition(0, 100);
            countDown.setFrame(0);
           
            startInfo = loader.loadImage("/press_info.png");
            bg=loader.loadImage("/bkg.png");
            Timecount.loadGraphics(digital);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private void UpLevel()
    {
        level++;
        switch(level)
        {
            case 1:nMine=10;break;
            case 2:nMine=15;break;
            case 3:nMine=20;break;
            case 4:nMine=30;break;
            case 5:nMine=40;break;
        }
        for(int i=0;i<9;i++)
            for(int j=0;j<9;j++)
            {
                ArrayOfBall[i][j].reset();
            }
        nMineOut=81-nMine;
        createdMineField=false;
        is_up_level=false;
        stopped=true;
       if(level!=1) countdownThread.run();
    }
    private void createBalls() {
        
        Ball ball;
        Random ran=new Random();
        int c,r;
        ArrayOfBall=new Ball[9][9];
        for(int i=0;i<9;i++)
            for(int j=0;j<9;j++)
            {
                ball=new Ball(26*i,32+26*j,balls);
                ArrayOfBall[i][j]=ball;
            }
        
    }
    
     private void CountNoMine(int last_i,int last_j){

        int r1=last_i==0?0:-1;
        int c1=last_j==0?0:-1;
        int r2=last_i==8?1:2;
        int c2=last_j==8?1:2;
        for(;r1<r2;r1++)
            for(int j=c1;j<c2;j++)
            {
                if(ArrayOfBall[last_i+r1][last_j+j].ismine) nMineAround++;
            }
    }
     private boolean isAround(int x,int y)
    {
         int r1=last_i==0?0:-1;
        int c1=last_j==0?0:-1;
        int r2=last_i==8?1:2;
        int c2=last_j==8?1:2;
        for(;r1<r2;r1++)
            for(int j=c1;j<c2;j++)
            {
               if(last_i+r1==x&&last_j+j==y) return true;
            }
        return false;
     }
       private void createMineField(){ /// cho nao co min cho nao ko co min //
           
//<<<<<<< .mine
           // ta chi can luu  0 1 thui, ko can luu so
        int c,r;
        Random ran=new Random();
        while(nMine>0)
        {
            c=ran.nextInt(9);
            r=ran.nextInt(9);
            if(!ArrayOfBall[c][r].ismine&&last_i!=c&&last_j!=r&&!isAround(c,r)){
                ArrayOfBall[c][r].ismine=true;
                nMine--;
            }
        }
//=======
           if(iscontinue){
                rw.read(false);
                for(int i=0; i< 9; i++)
                    for(int j= 0; j< 9; j++){
                        if(rw.ArrayMine[i][j] == 1)
                            ArrayOfBall[i][j].ismine=true;           
                    }
            ArrayOfBall[0][0].ismine=true;
           }
           else {
                   // int c,r;
                   ran=new Random();
                    while(nMine>0)
                    {
                        c=ran.nextInt(9);
                        r=ran.nextInt(9);
                        if(!ArrayOfBall[c][r].ismine&&last_i!=c&&last_j!=r){
                            ArrayOfBall[c][r].ismine=true;
                            nMine--;
                        }
                    }
           }
//>>>>>>> .r21
        createdMineField=true;
    }
       private boolean openField(int last_i,int last_j)
    {
           if(ArrayOfBall[last_i][last_j].ishide) return false;
            if(!ArrayOfBall[last_i][last_j].ismine)
                 {
                    nMineOut--;
                    if(nMineOut==0)
                    {
                        is_up_level = true;
                        UpLevel();
                        return false;
                    }
                    CountNoMine(last_i,last_j);
                     if(nMineAround==0)
                     {
                        
                         ArrayOfBall[last_i][last_j].ishide = true;
                         int r1=last_i==0?0:-1;
                         int c1=last_j==0?0:-1;
                          int r2=last_i==8?1:2;
                         int c2=last_j==8?1:2;
                         for(;r1<r2;r1++)
                        for(int j=c1;j<c2;j++)
                        {
                             openField(last_i+r1,last_j+j);
                         }
                         return true;
                     }
                     else
                     {
                         ArrayOfBall[last_i][last_j].setNoMineAround(nMineAround);
                         nMineAround=0;
                         return true;
                     }
                 }
            return false;
    }
       public void reset() {
   
        }
       protected void keyReleased(int keyCode) {
           if(stopped) return;
        switch (keyCode) {
            case GameCanvas.KEY_NUM2:{
               
               
            }
                break;
            case GameCanvas.KEY_NUM4:{
            }
                break;
            case GameCanvas.KEY_NUM6:{
            }
                break;
             case GameCanvas.KEY_NUM8:{
             }
                break;
            case GameCanvas.KEY_NUM1:{
            }
                break;
            case GameCanvas.KEY_NUM3:{
            }
                break;
             case GameCanvas.KEY_NUM5:{
                 openField(last_i,last_j);
             }
                break;
        }
    }
    public void exit() {
        exit();
    }
       
        
}
